/*
 * Copyright 2008 the Breachwalls OSS project and the Others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package com.breachwalls.mogen.generator;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 自動生成設定を持つプロパティ.
 * @author todoken
 * @version $Revision: 31 $
 */
public class LocalModelGenerationProperties implements ModelGenerationProperties {

    /**
     * デフォルトのプロパティファイル名.
     */
    public static final String PROPERTY_NAME = "mogen.properties";

    /**
     * 出力ファイルのエンコード指定のキー.
     */
    public static final String OUTPUT_ENCODING_KEY = "mogen.output.encoding";

    /**
     * 出力ファイルのディレクトリ指定のキー.
     */
    public static final String OUTPUT_DIRECTORY_KEY = "mogen.output.directory";

    /**
     * 自動生成設定ファイルのあるディレクトリ指定のキー.
     */
    public static final String CONFIG_DIRECTORY_KEY = "mogen.config.directory";

    /**
     * テンプレートのロケーション指定のキー.
     */
    public static final String TEMPLATE_LOCATION_KEY = "mogen.template.location";

    /**
     * ユーザーホームディレクトリの指定文字列.
     */
    private static final String USER_HOME = "user.home";

    /**
     * ロガー.
     */
    private static Logger logger = LoggerFactory.getLogger(LocalModelGenerationProperties.class);

    /**
     * ベースディレクトリ.
     */
    private File baseDirectory;

    /**
     * プロパティファイル.
     */
    private Properties properties;

    /**
     * コンストラクタ.
     */
    public LocalModelGenerationProperties() {
        this.properties = new Properties();
        InputStream is = null;
        ClassLoader loader = getClass().getClassLoader();
        try {
            is = loader.getResourceAsStream(PROPERTY_NAME);
            this.properties.load(is);
        } catch (IOException e) {
            // TODO change the Exception
            throw new RuntimeException(e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    logger.error("Failure closing " + PROPERTY_NAME, e);
                }
            }
        }

        URL url = loader.getResource(PROPERTY_NAME);
        File prop = new File(url.getFile());
        this.baseDirectory = prop.getParentFile();
    }

    /**
     * プロパティファイルを取得する.
     * @return プロパティファイル
     */
    protected Properties getProperties() {
        return properties;
    }

    /**
     * プロパティファイルを設定する.
     * @param newProperties プロパティファイル
     */
    protected void setProperties(Properties newProperties) {
        this.properties = newProperties;
    }

    /**
     * ベースディレクトリを取得する.
     * @return ベースディレクトリ
     */
    public File getBaseDirectory() {
        return baseDirectory;
    }

    /**
     * ベースディレクトリを設定する.
     * @param newBaseDirectory ベースディレクトリ
     */
    public void setBaseDirectory(File newBaseDirectory) {
        this.baseDirectory = newBaseDirectory;
    }

    /**
     * 自動生成ファイル出力先ディレクトリを取得する.
     * @return 自動生成ファイル出力先ディレクトリ
     */
    public File getOutputDirectory() {
        String dirname = properties.getProperty(OUTPUT_DIRECTORY_KEY);
        File dir = new File(System.getProperty(USER_HOME) + dirname);
        if (!dir.isDirectory()) {
            throw new IllegalArgumentException("[" + dir.getAbsolutePath() + "] is not directory.");
        }
        return dir;
    }

    /**
     * 自動生成設定ファイルのあるディレクトリを取得する.
     * @return 自動生成設定ファイルのあるディレクトリ
     */
    public File[] getConfigDirectories() {
        String dirname = properties.getProperty(CONFIG_DIRECTORY_KEY);
//        File dir = new File(System.getProperty(USER_HOME) + dirname);
        File dir = new File(baseDirectory, dirname);
        if (!dir.isDirectory()) {
            throw new IllegalArgumentException("[" + dir.getAbsolutePath() + "] is not directory.");
        }
        return new File[] {dir, getDefaultConfigFile()};
    }

    /**
     * デフォルトの自動生成設定ファイルのあるディレクトリを取得する.
     * @return デフォルトの自動生成設定ファイルのあるディレクトリ
     */
    protected File getDefaultConfigFile() {
        return this.baseDirectory;
    }

    /**
     * 出力ファイルの文字コードを取得する.
     * @return 出力ファイルの文字コード
     */
    public String getOutputEncoding() {
        return properties.getProperty(OUTPUT_ENCODING_KEY);
    }

    /**
     * テンプレートファイルのロケーションを取得する.
     * @return テンプレートファイルのロケーション
     */
    public File getTemplateLocation() {
        String dirname = properties.getProperty(TEMPLATE_LOCATION_KEY);
        if (StringUtils.isEmpty(dirname)) {
            ClassLoader loader = LocalModelGenerationProperties.class.getClassLoader();
            URL url = loader.getResource("mogen-templates");
            logger.info(url.getFile());
            return new File(url.getFile());
        }
        return new File(getBaseDirectory(), dirname);
    }

}
